home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / pennmush.000 / pennmush-1.50-p8-linux.tar / pennmush / chat.c < prev    next >
C/C++ Source or Header  |  1993-03-26  |  10KB  |  446 lines

  1. /* chat.c */
  2.  
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <math.h>
  6.  
  7. #include "config.h"
  8.  
  9. #if (CHAT_SYSTEM >=2)
  10.  
  11. #include "externs.h"
  12. #include "db.h"
  13. #include "interface.h"
  14. #include "match.h"
  15. #include "attrib.h"
  16. #include "chat.h"
  17.  
  18. CHTAB chantab[32];
  19.  
  20. int nchan(channel)
  21.      channel_type channel;
  22. {
  23.   /* given a flagwise channel, return its index, for chantab purposes */
  24.  
  25. #ifdef SUN_OS
  26.   return ((int) log2((double) channel));
  27. #else
  28.   return ((int) (log((double) channel) / log((double)2)));
  29. #endif                /* SUN_OS */
  30. }
  31.  
  32. channel_type find_channel(p)
  33.      char *p;
  34. {
  35.   /* given a channel name, return the flagwise channel */
  36.  
  37.   int b;
  38.   channel_type c = 0;
  39.  
  40.   if (!*p)
  41.     return c;
  42.  
  43.   for (b = 0; !c && (b < 32); b++) {
  44.     if (NChanPrivs(b) != CHP_FORBID) {
  45.       if ((NChanName(b) != NULL) && string_prefix(NChanName(b), p))
  46.     c = 1 << b;
  47.     }
  48.   }
  49.  
  50.   return c;
  51. }
  52.  
  53. channel_type find_channel_exact(name)
  54.      char *name;
  55. {
  56.   /* exact-match a channel, scanning all channels */
  57.   int b;
  58.   channel_type c = 0;
  59.  
  60.   for (b = 0; !c && (b < 32); b++) {
  61.     if ((NChanName(b) != NULL) && !strcasecmp(NChanName(b), name))
  62.       c = 1 << b;
  63.   }
  64.   return c;
  65. }
  66.  
  67. const char *channel_name(chan)
  68.      channel_type chan;
  69. {
  70.   /* given a flagwise channel, return its name */
  71.  
  72.   const char *n;
  73.  
  74.   n = chantab[nchan(chan)].name;
  75.  
  76.   return n;
  77. }
  78.  
  79. int convert_channel_privs(perms)
  80.      char *perms;
  81. {
  82.   /* given a permission level name, return the permission mask */
  83.  
  84.   if (string_prefix(perms, "public"))
  85.     return CHP_PUBLIC;
  86.   else if (string_prefix(perms, "admin"))
  87.     return CHP_ADMIN;
  88.   else if (string_prefix(perms, "wizard"))
  89.     return CHP_WIZARD;
  90.   else
  91.     return CHP_FORBID;
  92. }
  93.  
  94. const char *convert_channel_privname(privs)
  95.      int privs;
  96. {
  97.   /* given an integer permission, give permission name */
  98.  
  99.   switch (privs) {
  100.   case CHP_PUBLIC:
  101.     return "Public";
  102.   case CHP_ADMIN:
  103.     return "Admin";
  104.   case CHP_WIZARD:
  105.     return "Wizard";
  106.   default:
  107.     return "Forbidden";
  108.   }
  109. }
  110.  
  111. int add_channel(name, privs, pos)
  112.      char *name;
  113.      int privs;
  114.      int pos;    
  115. {
  116.   /* add a channel, return 1 on success, 0 on failure */
  117.  
  118.   int b;
  119.   int found = 0;
  120.  
  121.   /* find it */
  122.  
  123.   if (!pos) {
  124.     /* pick first empty spot, leave first few empty */
  125.  
  126.     for (b = 4; (b < 32) && !found; b++) {
  127.       if ((chantab[b].name == NULL) && (chantab[b].perms == CHP_FORBID))
  128.     found = 1;
  129.     }
  130.  
  131.     if (!found)
  132.       return 0;
  133.  
  134.     b--;            /* we're one ahead of the empty spot */
  135.   } else {
  136.     /* specified a place to put it */
  137.     b = nchan(pos);
  138.   }
  139.  
  140.   /* add it */
  141.   chantab[b].name = strdup(name);
  142.   chantab[b].perms = privs;
  143.  
  144.   return 1;
  145. }
  146.  
  147. void do_channel(player, name, com)
  148.      dbref player;
  149.      const char *name;
  150.      const char *com;
  151. {
  152.     /* join, quit, wipe, or who a channel */
  153.  
  154.     channel_type chan;
  155.     int i;
  156.  
  157.     if (Typeof(player) != TYPE_PLAYER) {
  158.     notify(player, "Sorry, the chat system is only for players.");
  159.     return;
  160.     }
  161.  
  162.     if (!name && !*name) {
  163.     notify(player, "You need to specify a channel.");
  164.     return;
  165.     }
  166.     if (!com && !*com) {
  167.     notify(player, "What do you want to do with that channel?");
  168.     return;
  169.     }
  170.  
  171.     chan = find_channel(name);
  172.  
  173.     if (!chan) {
  174.     notify(player, "I don't recognize that channel.");
  175.     return;
  176.     }
  177.  
  178.     if (!ChannelPermit(player, chan)) {
  179.     notify(player, "Sorry, you aren't authorized to do that.");
  180.     return;
  181.     }
  182.  
  183.     /* add, delete, wipe, or check who is on a channel */
  184.     if (!strcasecmp("on", com)) {
  185.     if (!OnChannel(player, chan)) {
  186.         Channels(player) |= chan;
  187.         notify(player, "Channel added.");
  188.         channel_broadcast(chan, "<%s> %s has joined this channel.", 
  189.                   channel_name(chan), Name(player));
  190.     } else {
  191.         notify(player, "You are already on that channel.");
  192.     }
  193.     return;
  194.     } else if (!strcasecmp("off", com)) {
  195.     if (OnChannel(player, chan)) {
  196.         Channels(player) &= ~chan;
  197.         notify(player, "Channel deleted.");
  198.         channel_broadcast(chan, "<%s> %s has left this channel.", 
  199.                   channel_name(chan), Name(player));
  200.     } else {
  201.         notify(player, "You are not on that channel.");
  202.     }
  203.     return;
  204.     } else if (!strcasecmp("wipe", com)) {
  205.     if (!Wizard(player)) {
  206.         notify(player, "Such power is not within you.");
  207.     } else {
  208.         for (i = 0; i < db_top; i++)
  209.         Channels(i) &= ~chan;
  210.         notify(player, "Channel wiped.");
  211.     }
  212.     return;
  213.     } else if (!strcasecmp("who", com)) {
  214.     do_channel_who(player, chan);
  215.     return;
  216.     } else {
  217.     notify(player, "I don't understand what you want to do.");
  218.     return;
  219.     }
  220. }
  221.  
  222. void do_chat(player, chan, arg1)
  223.      dbref player;
  224.      channel_type chan;
  225.      const char *arg1;
  226. {
  227.   /* send a message to a channel */
  228.  
  229.   int key;
  230.   const char *gap;
  231.  
  232.   if (!chan) {
  233.     notify(player, "I don't recognize that channel.");
  234.     return;
  235.   }
  236.  
  237.   if (!ChannelPermit(player, chan)) {
  238.     notify(player, "Sorry, you're not authorized to be on that channel.");
  239.     return;
  240.   }
  241.  
  242.   /* figure out what kind of message we have */
  243.   gap = " ";
  244.   switch (*arg1) {
  245.   case SEMI_POSE_TOKEN:
  246.     gap = "";
  247.   case POSE_TOKEN:
  248.     key = 1;
  249.     arg1 = arg1 + 1;
  250.     break;
  251.   case NULL:
  252.     key = 3;
  253.     break;
  254.   default:
  255.     key = 2;
  256.     break;
  257.   }
  258.  
  259.   /* now send out the message. If the player isn't on that channel, tell
  260.    * him what he said.
  261.    */
  262.   switch (key) {
  263.   case 1:
  264.     channel_broadcast(chan, "<%s> %s%s%s", channel_name(chan),
  265.               Name(player), gap, arg1);
  266.     if (!OnChannel(player, chan))
  267.       notify(player, tprintf("To channel %s: %s%s%s", channel_name(chan),
  268.                  Name(player), gap, arg1));
  269.     break;
  270.   case 2:
  271.     channel_broadcast(chan, "<%s> %s says, \"%s\"", channel_name(chan),
  272.               Name(player), arg1);
  273.     if (!OnChannel(player, chan))
  274.       notify(player, tprintf("To channel %s: %s says, \"%s\"",
  275.                  channel_name(chan), Name(player), arg1));
  276.     break;
  277.   case 3:
  278.     notify(player, "What do you want to say to that channel?");
  279.     break;
  280.   }
  281. }
  282.  
  283. void do_chan_admin(player, name, perms, flag)
  284.      dbref player;
  285.      char *name;
  286.      char *perms;
  287.      int flag;
  288. {
  289.   /* wipe, add, remove, rename, or change the permissions of a channel */
  290.  
  291.   int chan, privs;
  292.   int i;
  293.  
  294.   if (!Wizard(player)) {
  295.     notify(player, "Only a wizard may modify channels.");
  296.     return;
  297.   }
  298.  
  299.   chan = privs = 0;
  300.  
  301.   switch (flag) {
  302.   case 0:
  303.     /* add a channel */
  304.     if (*name == '\0')  {
  305.       notify(player, "You must name the channel.");
  306.       return;
  307.     }
  308.     if (*perms == '\0') {
  309.       notify(player, "You must specify the restrictions on the channel.");
  310.       return;
  311.     }
  312.     /* make sure the channel name is unique */
  313.     if (find_channel(name) != 0) {
  314.       notify(player, "The channel needs a more unique name.");
  315.       return;
  316.     }
  317.     /* get the permissions. Invalid specifications default to "forbidden" */
  318.     privs = convert_channel_privs(perms);
  319.     if (privs == CHP_FORBID)
  320.       notify(player, "Warning: channel will be created locked to all.");
  321.     if (add_channel(name, privs, 0))
  322.       notify(player, "Channel created.");
  323.     else
  324.       notify(player, "No more room in the channel table.");
  325.     return;
  326.     break;            /* NOT REACHED */
  327.   case 1:
  328.     /* remove a channel */
  329.     if (*name == '\0') {
  330.       notify(player, "You must specify a channel to remove.");
  331.       return;
  332.     }
  333.     chan = find_channel(name);
  334.     if (!chan) {
  335.       notify(player, "That channel does not appear to exist.");
  336.       return;
  337.     }
  338.     /* zap the channel */
  339.     /* remove everyone from the channel */
  340.     for (i = 0; i < db_top; i++)
  341.       if (Typeof(i) == TYPE_PLAYER)
  342.     db[i].channels &= ~chan;
  343.     free(chantab[nchan(chan)].name);
  344.     chantab[nchan(chan)].perms = CHP_FORBID;
  345.     notify(player, "Channel removed.");
  346.     return;
  347.     break;            /* NOT REACHED */
  348.   case 2:
  349.     /* rename a channel */
  350.     if (*name == '\0') {
  351.       notify(player, "You must specify a channel to rename.");
  352.       return;
  353.     }
  354.     if (*perms == '\0')  {
  355.       notify(player, "What do you want to rename the channel to?");
  356.       return;
  357.     }
  358.     /* make sure channel exists */
  359.     chan = find_channel_exact(name);
  360.     if (!chan) {
  361.       notify(player, "That channel does not appear to exist.");
  362.       return;
  363.     }
  364.     /* make sure the channel name is unique */
  365.     if (find_channel(perms) != 0) {
  366.       notify(player, "The channel needs a more unique name.");
  367.       return;
  368.     }
  369.     free(chantab[nchan(chan)].name);
  370.     chantab[nchan(chan)].name = strdup(perms);
  371.     notify(player, "Channel renamed.");
  372.     break;
  373.   case 3:
  374.     /* change the permissions on a channel */
  375.     if (*name == '\0')  {
  376.       notify(player, "You must specify a channel.");
  377.       return;
  378.     }
  379.     chan = find_channel_exact(name);
  380.     if (!chan) {
  381.       notify(player, "That channel does not appear to exist.");
  382.       return;
  383.     }
  384.     if (*perms == '\0') {
  385.       notify(player, "You must specify the restrictions on the channel.");
  386.       return;
  387.     }
  388.     privs = convert_channel_privs(perms);
  389.     if (privs == CHP_FORBID)
  390.       notify(player, "Warning: channel will be locked to all.");
  391.     chantab[nchan(chan)].perms = privs;
  392.     notify(player, "Permissions on channel changed.");
  393.     return;
  394.     break;            /* NOT REACHED */
  395.   }
  396. }
  397.  
  398. void do_channel_list(player)
  399.      dbref player;
  400. {
  401.   int b;
  402.  
  403.   if (Wizard(player)) {
  404.     notify(player, "Channel        Name         Privs");
  405.  
  406.     for (b = 0; b < 32; b++) {
  407.       if ((chantab[b].name == NULL) && (chantab[b].perms == CHP_FORBID))
  408.     continue;
  409.       notify(player, tprintf("0x%-8x     %-10s   %s", 
  410.                  (int) pow((double) 2, (double) b),
  411.                  chantab[b].name,
  412.                  convert_channel_privname(chantab[b].perms)));
  413.     }
  414.   } else {
  415.     notify(player, "Name         Privs");
  416.  
  417.     for (b = 0; b < 32; b++) {
  418.       if ((chantab[b].name == NULL) && (chantab[b].perms == CHP_FORBID))
  419.     continue;
  420.       notify(player, tprintf("%-10s   %s", chantab[b].name,
  421.                  convert_channel_privname(chantab[b].perms)));
  422.     }
  423.   }
  424. }
  425.  
  426.  
  427. void init_chat()
  428. {
  429.   /* clear out the channel table and do initialization of defaults. */
  430.  
  431.   int b;
  432.  
  433.   for (b = 0; b < 32; b++) {
  434.     chantab[b].name = NULL;
  435.     chantab[b].perms = CHP_FORBID;
  436.   }
  437.  
  438.   add_channel("Public", CHP_PUBLIC, 0x10);
  439.   add_channel("Code", CHP_PUBLIC, 0x20);
  440.   add_channel("Mush", CHP_PUBLIC, 0x40);
  441.   add_channel("Admin", CHP_ADMIN, 0x10000);
  442.   add_channel("Wizard", CHP_WIZARD, 0x1000000);
  443. }
  444.  
  445. #endif                /* CHAT_SYSTEM */
  446.